package com.tianhao.luo.springbusiness.service;

import com.tianhao.luo.springbusiness.entity.User;

/**
 * 学习spring的声明式事务管理
 *
 * 1 主要是传播机制{@link org.springframework.transaction.annotation.Propagation}
 *
 * 2 主要是隔离级别
 *
 * @author tianhao.luo@hand-china.com
 */
public interface UserService {

    /**
     * 测试REQUIRED
     *
     * 默认使用的事务传播行为
     * 如果当前存在事务，则加入该事务；如果当前没有事务，则创建一个新的事务
     */
    void testPropagationOfRequired();

    /**
     * 测试SUPPORTS
     *
     *
     * SUPPORTS：支持当前事务，如果当前事务不存在，那么本方法也不进行事务控制
     * 简言之，如果当前是有事务的，则加入该事务；如果没有事务，则本方法也不创建事务
     */
    void testPropagationOfSupports();

    /**
     * MANDATORY
     *
     * 如果当前没有事务，则会抛出异常；如果有事务，则加入该事务
     */
    void testPropagationOfMandatory();

    /**
     * REQUIRES_NEW
     *
     * 创建一个新事务，如果当前有事务，就暂停当前事务，而使用这个新事务
     */
    void testPropagationOfRequiresNew();

    /**
     * NOT_SUPPORTED
     */
    void testPropagationOfNotSupport();

    /**
     * NEVER
     */
    void testPropagationOfNever();

    /**
     * NESTED
     */
    void testPropagationOfNested();

    /**
     * 测试脏读在什么隔离级别下出现
     */
    void testDirtyRead();

    /**
     *
     * 测试丢失修改
     *
     * @param user 测试的user
     */
    void testLostEdit(User user);


    /**
     * 初始化一条user数据
     *
     * @return 初始化的user数据
     */
    User initUserData();


    /**
     * 测试不可重复读
     *
     * 1 注意测试时需要关闭mybatis的一级缓存，在select标签中添加flushCache="true"，它表示每次查询都是从数据库来，而不会从mybatis的缓存中获取
     *
     * @param user 已有数据的查询条件参数
     */
    void testNotRepeatableRead(User user);


    /**
     * 测试幻读
     *
     * 给userDao添加一个selectAll方法，来模拟出现幻读的情况
     *
     */
    void testPhantomRead();

}
